﻿using Art_To_Eagle.Lib;
using Art_To_Eagle.Lib.EagleLib;
using Art_To_Eagle.Lib.EagleLib.Structure;
using Art_To_Eagle.Lib.Safebooru;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Image = System.Windows.Controls.Image;

namespace Art_To_Eagle
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Eagle.UpdateState();
                    if (Eagle.Connected)
                    {
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            EagleState.Content = "已启动";
                        });
                    }
                    else
                    {
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            EagleState.Content = "未启动";
                        });
                    }
                    Thread.Sleep(1000);
                }
            });
            ReadPage();
        }

        private int page = 1;
        private readonly Dictionary<Image, Post> PD = new Dictionary<Image, Post>();

        private void ReadPage()
        {PostList.SelectedItems.Clear();
            var posts = Lib.Safebooru.PostList.Get(page);
            Application.Current.Dispatcher.Invoke(() =>
            {
                PostList.SelectedItems.Clear();
                PostList.Items.Clear();
                if (posts != null)
                {
                    for (int i = 0; i < posts.Length; i++)
                    {
                        var img = new Image();
                        PD[img] = posts[i];
                        var url = posts[i].PreviewImage;
                        img.Loaded += async (o, e) =>
                        {
                            System.Drawing.Image image = null;
                            await Task.Run(() =>
                            {
                                try
                                {
                                    image = url.GetImageFromNet();
                                }
                                catch
                                {
                                }
                            });
                            if (image != null)
                            {
                                Application.Current.Dispatcher.Invoke(() =>
                                {
                                    img.Source = ((Bitmap)image.Clone()).ToBitmapImage();
                                });
                            }
                        };
                        img.Unloaded += (o, e) => PD[img] = null;
                        PostList.Items.Add(img);
                    }
                }
            });
        }

        private void Button_JumpToPage(object sender, RoutedEventArgs e)
        {
            if (int.TryParse(PageInput.Text, out int p))
                if (p > 0)
                    page = p;
            ReadPage();
        }

        private void Button_NextPage(object sender, RoutedEventArgs e)
        {
            page++;
            Application.Current.Dispatcher.Invoke(() => PageInput.Text = page.ToString());
            ReadPage();
        }

        private void Button_LastPage(object sender, RoutedEventArgs e)
        {
            page--;
            if (page < 1)
                page = 1;
            Application.Current.Dispatcher.Invoke(() => PageInput.Text = page.ToString());
            ReadPage();
        }

        private void Button_SelectAll(object sender, RoutedEventArgs e)
        {
            PostList.SelectedItems.Clear();
            for (int i = 0; i < PostList.Items.Count; i++)
                PostList.SelectedItems.Add(PostList.Items[i]);
        }

        private void Button_CancelAll(object sender, RoutedEventArgs e)
            => PostList.SelectedItems.Clear();

        private void Button_AddToEagle(object sender, RoutedEventArgs e)
        {
            var list = new Image[PostList.SelectedItems.Count];
            var list2 = new Post[PostList.SelectedItems.Count];
            for (int i = 0; i < PostList.SelectedItems.Count; i++)
            {
                list[i] = (Image)PostList.SelectedItems[i];
                list2[i] = PD[list[i]];
            }
            PostList.SelectedItems.Clear();
            for (int i = 0; i < list.Length; i++)
            {
                var post = list2[i];
                Download(post.FileUrl, Post.GetPostTitle(post.Id), post.FromPage, post.Tags, list[i].Source);
            }
        }

        private readonly ArrayList DownloadList = new ArrayList();

        public void Download(string url, string name, string website = null, string[] tags = null, ImageSource pic = null)
        {
            var di = new DownloadImage(new WebImage
            {
                Url = url,
                Name = name,
                Website = website,
                Tags = tags
            }, (info) => Api.AddImageFromUrl(info));
            DownloadList.Add(di);
            Application.Current.Dispatcher.Invoke(()
                => DownloadListBox.Items.Add(new Lib.Windows.DownloadItem(di, pic)));
        }
    }

    public class DownloadImage
    {
        private readonly DownloadManager DM;
        public long ReceivedBytes { get => DM == null ? 0 : DM.ReceivedBytes; }
        public long TotalBytes { get => DM == null ? 0 : DM.TotalBytes; }
        public double Progress { get => DM == null ? 0 : DM.Progress; }
        public byte[] Result { get => DM?.Result; }
        public Exception Exception { get => DM?.Exception; }
        public bool ShutdownFlag { get => (bool)DM?.ShutdownFlag; }
        public WebImage Info;

        public DownloadImage(WebImage info, Action<WebImage> callback = null)
        {
            Info = info;
            DM = new DownloadManager(info.Url);
            DM.Start((bs) =>
            {
                var pic = new MemoryImage(System.Drawing.Image.FromStream(new MemoryStream(bs)));
                Info.Url = "data:" + pic.DataUriScheme + ";base64," + pic.ToBase64();
                callback?.Invoke(Info);
            });
        }

        public void Shutdown() => DM.Shutdown();
    }
}
